import { Router } from 'express'
import { body, validationResult } from 'express-validator'
import { supabase } from '../server'
import { logger } from '../utils/logger'
import { asyncHandler, createError } from '../middleware/errorHandler'
import { AuthenticatedRequest, logUserActivity } from '../middleware/auth'

const router = Router()

// Helper function to check validation results
const checkValidation = (req: any, res: any) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    return res.status(400).json({
      success: false,
      message: 'Validation failed',
      errors: errors.array()
    })
  }
  return null
}

// Get complete user profile with subscription info
router.get('/',
  logUserActivity('view_complete_profile'),
  asyncHandler(async (req: AuthenticatedRequest, res) => {
    const userId = req.user?.id

    if (!userId) {
      return res.status(401).json({
        success: false,
        message: 'Authentication required'
      })
    }

    try {
      // Get user profile
      const { data: profile, error: profileError } = await supabase
        .from('user_profiles')
        .select('*')
        .eq('user_id', userId)
        .single()

      if (profileError || !profile) {
        return res.status(404).json({
          success: false,
          message: 'User profile not found'
        })
      }

      // Get active subscription
      const { data: subscription, error: subError } = await supabase
        .from('subscriptions')
        .select('*')
        .eq('user_id', userId)
        .eq('status', 'active')
        .order('created_at', { ascending: false })
        .limit(1)
        .single()

      // Get recent activity (last 10 items)
      const { data: recentActivity } = await supabase
        .from('user_activity_logs')
        .select('action, timestamp, ip_address')
        .eq('user_id', userId)
        .order('timestamp', { ascending: false })
        .limit(10)

      const completeProfile = {
        ...profile,
        subscription: subscription || null,
        recent_activity: recentActivity || []
      }

      // Remove sensitive data
      delete completeProfile.gdpr_consent_date

      res.json({
        success: true,
        profile: completeProfile
      })

    } catch (error) {
      logger.error('Get complete profile error', { 
        error: error instanceof Error ? error.message : String(error), 
        userId 
      })
      throw error
    }
  })
)

// Update profile avatar
router.post('/avatar',
  [
    body('avatar_url').isURL().withMessage('Valid avatar URL is required')
  ],
  logUserActivity('update_avatar'),
  asyncHandler(async (req: AuthenticatedRequest, res) => {
    const validationError = checkValidation(req, res)
    if (validationError) return validationError

    const userId = req.user?.id
    const { avatar_url } = req.body

    if (!userId) {
      return res.status(401).json({
        success: false,
        message: 'Authentication required'
      })
    }

    try {
      const { data: profile, error } = await supabase
        .from('user_profiles')
        .update({
          avatar_url,
          updated_at: new Date().toISOString()
        })
        .eq('user_id', userId)
        .select()
        .single()

      if (error) {
        logger.error('Avatar update failed', { error: error.message, userId })
        throw createError('Avatar update failed: ' + error.message, 400)
      }

      logger.info('Avatar updated successfully', { userId })

      res.json({
        success: true,
        message: 'Avatar updated successfully',
        avatar_url
      })

    } catch (error) {
      logger.error('Update avatar error', { 
        error: error instanceof Error ? error.message : String(error), 
        userId 
      })
      throw error
    }
  })
)

// Verify phone number
router.post('/verify-phone',
  [
    body('phone_number').isMobilePhone('any'),
    body('verification_code').isLength({ min: 6, max: 6 })
  ],
  logUserActivity('verify_phone'),
  asyncHandler(async (req: AuthenticatedRequest, res) => {
    const validationError = checkValidation(req, res)
    if (validationError) return validationError

    const userId = req.user?.id
    const { phone_number, verification_code } = req.body

    if (!userId) {
      return res.status(401).json({
        success: false,
        message: 'Authentication required'
      })
    }

    try {
      // In a real implementation, you would verify the code with an SMS service
      // For now, we'll accept any 6-digit code
      if (!/^\d{6}$/.test(verification_code)) {
        return res.status(400).json({
          success: false,
          message: 'Invalid verification code'
        })
      }

      const { data: profile, error } = await supabase
        .from('user_profiles')
        .update({
          phone_number,
          phone_verified: true,
          updated_at: new Date().toISOString()
        })
        .eq('user_id', userId)
        .select()
        .single()

      if (error) {
        logger.error('Phone verification failed', { error: error.message, userId })
        throw createError('Phone verification failed: ' + error.message, 400)
      }

      logger.info('Phone number verified', { userId, phoneNumber: phone_number })

      res.json({
        success: true,
        message: 'Phone number verified successfully'
      })

    } catch (error) {
      logger.error('Phone verification error', { 
        error: error instanceof Error ? error.message : String(error), 
        userId 
      })
      throw error
    }
  })
)

// Get profile statistics
router.get('/stats',
  logUserActivity('view_profile_stats'),
  asyncHandler(async (req: AuthenticatedRequest, res) => {
    const userId = req.user?.id

    if (!userId) {
      return res.status(401).json({
        success: false,
        message: 'Authentication required'
      })
    }

    try {
      // Get subscription usage
      const { data: subscription } = await supabase
        .from('subscriptions')
        .select('usage_metrics, features, created_at, plan_type')
        .eq('user_id', userId)
        .eq('status', 'active')
        .single()

      // Get activity count for current month
      const monthStart = new Date()
      monthStart.setDate(1)
      monthStart.setHours(0, 0, 0, 0)

      const { count: monthlyActivity } = await supabase
        .from('user_activity_logs')
        .select('id', { count: 'exact', head: true })
        .eq('user_id', userId)
        .gte('timestamp', monthStart.toISOString())

      // Get total sessions count
      const { count: totalSessions } = await supabase
        .from('user_sessions')
        .select('id', { count: 'exact', head: true })
        .eq('user_id', userId)

      // Calculate days since account creation
      const { data: profile } = await supabase
        .from('user_profiles')
        .select('created_at, last_login')
        .eq('user_id', userId)
        .single()

      const daysSinceCreation = profile ? 
        Math.floor((Date.now() - new Date(profile.created_at).getTime()) / (1000 * 60 * 60 * 24)) : 0

      const stats = {
        account: {
          days_since_creation: daysSinceCreation,
          last_login: profile?.last_login,
          total_sessions: totalSessions || 0,
          monthly_activity: monthlyActivity || 0
        },
        subscription: {
          plan_type: subscription?.plan_type || 'free',
          days_since_subscription: subscription ? 
            Math.floor((Date.now() - new Date(subscription.created_at).getTime()) / (1000 * 60 * 60 * 24)) : 0,
          usage_metrics: subscription?.usage_metrics || null,
          features: subscription?.features || null
        }
      }

      res.json({
        success: true,
        stats
      })

    } catch (error) {
      logger.error('Get profile stats error', { 
        error: error instanceof Error ? error.message : String(error), 
        userId 
      })
      throw error
    }
  })
)

// Update account settings
router.put('/settings',
  [
    body('two_factor_enabled').optional().isBoolean(),
    body('login_alerts').optional().isBoolean(),
    body('session_timeout').optional().isInt({ min: 15, max: 1440 }),
    body('password_strength_requirement').optional().isIn(['basic', 'medium', 'strong']),
    body('allowed_login_methods').optional().isArray()
  ],
  logUserActivity('update_account_settings'),
  asyncHandler(async (req: AuthenticatedRequest, res) => {
    const validationError = checkValidation(req, res)
    if (validationError) return validationError

    const userId = req.user?.id
    const settings = req.body

    if (!userId) {
      return res.status(401).json({
        success: false,
        message: 'Authentication required'
      })
    }

    try {
      // Get current profile
      const { data: currentProfile } = await supabase
        .from('user_profiles')
        .select('account_settings')
        .eq('user_id', userId)
        .single()

      if (!currentProfile) {
        return res.status(404).json({
          success: false,
          message: 'User profile not found'
        })
      }

      const updatedSettings = {
        ...currentProfile.account_settings,
        ...settings
      }

      const { data: profile, error } = await supabase
        .from('user_profiles')
        .update({
          account_settings: updatedSettings,
          updated_at: new Date().toISOString()
        })
        .eq('user_id', userId)
        .select()
        .single()

      if (error) {
        logger.error('Account settings update failed', { error: error.message, userId })
        throw createError('Account settings update failed: ' + error.message, 400)
      }

      logger.info('Account settings updated', { userId, settings: Object.keys(settings) })

      res.json({
        success: true,
        message: 'Account settings updated successfully',
        settings: updatedSettings
      })

    } catch (error) {
      logger.error('Update account settings error', { 
        error: error instanceof Error ? error.message : String(error), 
        userId 
      })
      throw error
    }
  })
)

// Get notification history
router.get('/notifications',
  logUserActivity('view_notifications'),
  asyncHandler(async (req: AuthenticatedRequest, res) => {
    const userId = req.user?.id

    if (!userId) {
      return res.status(401).json({
        success: false,
        message: 'Authentication required'
      })
    }

    try {
      // In a real implementation, you would have a notifications table
      // For now, we'll return recent activity as mock notifications
      const { data: activities } = await supabase
        .from('user_activity_logs')
        .select('action, timestamp')
        .eq('user_id', userId)
        .order('timestamp', { ascending: false })
        .limit(20)

      const mockNotifications = (activities || []).map((activity, index) => ({
        id: index + 1,
        type: 'activity',
        title: `Account Activity: ${activity.action.replace('_', ' ').toUpperCase()}`,
        message: `You performed action: ${activity.action}`,
        timestamp: activity.timestamp,
        read: index > 5, // Mark older notifications as read
        category: 'system'
      }))

      res.json({
        success: true,
        notifications: mockNotifications
      })

    } catch (error) {
      logger.error('Get notifications error', { 
        error: error instanceof Error ? error.message : String(error), 
        userId 
      })
      throw error
    }
  })
)

// Mark notifications as read
router.put('/notifications/read',
  [body('notification_ids').isArray()],
  logUserActivity('mark_notifications_read'),
  asyncHandler(async (req: AuthenticatedRequest, res) => {
    const validationError = checkValidation(req, res)
    if (validationError) return validationError

    const userId = req.user?.id
    const { notification_ids } = req.body

    if (!userId) {
      return res.status(401).json({
        success: false,
        message: 'Authentication required'
      })
    }

    // In a real implementation, you would update the notifications table
    logger.info('Notifications marked as read', { userId, count: notification_ids.length })

    res.json({
      success: true,
      message: `${notification_ids.length} notifications marked as read`
    })
  })
)

export default router